package com.innoking.docsys.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.innoking.docsys.user.module.UpmsUserVO;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTUtil {


    public static String getToken(UpmsUserVO user, long maxAge) {
        String token="";
        token= JWT.create().withAudience( String.valueOf(user.getUserId()) )
                .withExpiresAt(new Date(System.currentTimeMillis() + maxAge))//签名过期的时间
                .sign(Algorithm.HMAC256( SECRET ) );
        return token;
    }

    private static final String SECRET = "XX#$%()(#*!()!KL<><MQLMNQNQJQK sdfkjsdrow32234545fdf>?N<:{LWPW";

    private static final String EXP = "exp";

    private static final String PAYLOAD = "payload";

    //加密，传入一个对象和有效期
    public static <T> String sign(T object, long maxAge) {

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");

        Algorithm algorithm = Algorithm.HMAC256(SECRET);

        String token = com.auth0.jwt.JWT.create()
                .withHeader(map)
                /*设置 载荷 Payload*/
                .withClaim("loginName", "zhuoqianmingyue")
                .withIssuer("SERVICE")//签名是有谁生成 例如 服务器
                .withSubject("this is test token")//签名的主题
                //.withNotBefore(new Date())//该jwt都是不可用的时间
                .withAudience("APP")//签名的观众 也可以理解谁接受签名的
                .withIssuedAt(new Date()) //生成签名的时间
                .withExpiresAt(new Date(System.currentTimeMillis() + maxAge))//签名过期的时间
                /*签名 Signature */
                .sign(algorithm);

                return  token;

                //jwt2.4之前方法
//        try {
//            final JWTSigner signer = new JWTSigner(SECRET);
//            final Map<String, Object> claims = new HashMap<>();
//            ObjectMapper mapper = new ObjectMapper();
//            String jsonString = mapper.writeValueAsString(object);
//            claims.put(PAYLOAD, jsonString);
//            claims.put(EXP, System.currentTimeMillis() + maxAge);
//            return signer.sign(claims);
//        } catch(Exception e) {
//            return null;
//        }
    }

    //解密，传入一个加密后的token字符串和解密后的类型
    public static<T> T unsign(String token, Class<T> classT) {
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        JWTVerifier verifier = com.auth0.jwt.JWT.require(algorithm)
                .withIssuer("SERVICE")
                .build();
        DecodedJWT jwt = verifier.verify(token);

     //   String  userId = JWT.decode(token).getAudience().get(0);
        String subject = jwt.getSubject();
        String userId = jwt.getAudience().get(0);

        Map<String, Claim> claims = jwt.getClaims();
        Date  expDate =  jwt.getExpiresAt();
        if(expDate .compareTo( new Date() ) <0 ){
            System.out.println("token 过期");
        }

        return null;

        //jwt2.4之前方法
//        final JWTVerifier verifier = new JWTVerifier(SECRET);
//        try {
//            final Map<String,Object> claims= verifier.verify(jwt);
//            if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
//                long exp = (Long)claims.get(EXP);
//                long currentTimeMillis = System.currentTimeMillis();
//                if (exp > currentTimeMillis) {
//                    String json = (String)claims.get(PAYLOAD);
//                    ObjectMapper objectMapper = new ObjectMapper();
//                    return objectMapper.readValue(json, classT);
//                }
//            }
//            return null;
//        } catch (Exception e) {
//            return null;
//        }
    }

}